package concurrent.mthread.cycyclicbarrier;

import java.util.Arrays;
import java.util.concurrent.CyclicBarrier;

/**
 * 障栅
 *
 * @author scylla
 * @version V1.0
 * @project echo-java-base
 * @title 障栅示例
 * @package concurrent.mthread.cycyclicbarrier
 * @since 2021/12/6 1:20 下午
 */
public class CyclicBarrierDemo {

    static class Tourist extends Thread {
        CyclicBarrier barrier;

        public Tourist(CyclicBarrier barrier) {
            this.barrier = barrier;
        }

        @Override
        public void run() {
            try {
                //模拟独立运行
                Thread.sleep((int) (Math.random() * 1000));

                //集合点 A
                barrier.await();

                System.out.println(this.getName() + " arrived A " + System.currentTimeMillis());

                //集合后模拟各自独立运行
                Thread.sleep((int) (Math.random() * 1000));

                //集合点 B
                barrier.await();
                System.out.println(this.getName() + " arrived B " + System.currentTimeMillis());

            } catch (Exception e) {
                System.err.println(Arrays.toString(e.getStackTrace()));
            }
        }

        public static void main(String[] args) {
            int num = 3;
            //模拟三个游客线程
            Tourist[] tourists = new Tourist[num];
            //构造障栅  所有线程进入后执行
            CyclicBarrier barrier = new CyclicBarrier(num, () -> {
                System.out.println("all arrived " + System.currentTimeMillis() + " executed by " + Thread.currentThread().getName());
            });

            //顺序运行三个线程
            for (int i = 0; i < num; i++) {
                tourists[i] = new Tourist(barrier);
                tourists[i].start();
            }

        }
    }

}
